package rpc.simple.impl.tag3;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.Socket;

/**
 * XXX
 *
 * @author mengzhang6
 * @date 2019/1/3 10:28
 */
public class SimpleRpcFrameworkInvocationHandler implements InvocationHandler {

    private String host;
    private Integer port;

    private SimpleRpcFrameworkInvocationHandler(String host, Integer port) {
        this.host = host;
        this.port = port;
    }

    public static SimpleRpcFrameworkInvocationHandler newInstice(String host, Integer port) {
        return new SimpleRpcFrameworkInvocationHandler(host, port);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
        Socket socket = new Socket(host, port);

        try (
                ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
        ) {
            output.writeUTF(method.getName());
            output.writeObject(method.getParameterTypes());
            output.writeObject(arguments);
            Object result = input.readObject();
            if (result instanceof Throwable) {
                throw (Throwable) result;
            }
            return result;
        } finally {
            socket.close();
        }

    }
}
